package com.tyrone.gateway.registry;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.Service;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.sun.org.apache.bcel.internal.generic.IREM;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.lang3.ObjectUtils;

import java.util.*;

@Slf4j
public class NacosRegistry implements Registry {

    private static NamingService NAMING_SERVICE;

    @Override
    public void registry(GatewayInfo gatewayInfo) {
        assert gatewayInfo != null;
        try {
            NAMING_SERVICE = NamingFactory.createNamingService(gatewayInfo.getRegistryAddr());
            NAMING_SERVICE.registerInstance(gatewayInfo.getName(), gatewayInfo.getIp(), gatewayInfo.getPort(), gatewayInfo.getClusterName());
        } catch (Exception e) {
            log.error("NacosRegistry registry error:", e);
        }

    }

    @Override
    public InstanceInfo selectOneHealthyInstance(ServiceInfo serviceInfo) {
        assert NAMING_SERVICE != null;
        InstanceInfo instanceInfo = null;
        try {
            Instance instance = NAMING_SERVICE.selectOneHealthyInstance(serviceInfo.getName());
            instanceInfo = buildInstanceInfo(instance);
        } catch (Exception e) {
            log.error("NacosRegistry selectOneHealthyInstance error:", e);
        }
        return instanceInfo;
    }

    @Override
    public List<InstanceInfo> getHealthyInstances(ServiceInfo serviceInfo) {
        assert NAMING_SERVICE != null;
        List<InstanceInfo> instanceInfos = null;
        try {
            List<Instance> instances = NAMING_SERVICE.selectInstances(serviceInfo.getName(), Boolean.TRUE);
            instanceInfos = convertToInstanceInfo(instances);
        } catch (Exception e) {
            log.error("NacosRegistry#getHealthyInstances error:", e);
        }
        return instanceInfos == null ? new ArrayList<>() : instanceInfos;
    }

    @Override
    public void deregister(GatewayInfo gatewayInfo) {
        assert NAMING_SERVICE != null;
        try {
            NAMING_SERVICE.deregisterInstance(gatewayInfo.getName(), gatewayInfo.getIp(), gatewayInfo.getPort());
        } catch (Exception e) {
            log.error("NacosRegistry#deregister error:", e);
        }
    }

    private List<InstanceInfo> convertToInstanceInfo(List<Instance> instances) {
        if (ObjectUtils.isEmpty(instances)) return new ArrayList<>();
        List<InstanceInfo> instanceInfos = new ArrayList<>();
        for (Instance instance : instances) {
            instanceInfos.add(buildInstanceInfo(instance));
        }
        return instanceInfos;
    }

    private InstanceInfo buildInstanceInfo(Instance instance) {
        assert instance != null;
        return InstanceInfo.builder()
                .ip(instance.getIp())
                .port(instance.getPort())
                .weight(instance.getWeight())
                .serviceName(instance.getServiceName())
                .healthy(instance.isHealthy())
                .build();
    }


}
